package com.chatim.nonamechatim.netty.handler;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chatim.nonamechatim.netty.common.Command;
import com.chatim.nonamechatim.netty.CommandType;
import com.chatim.nonamechatim.netty.common.WSRes;
import com.chatim.nonamechatim.pojo.User;
import com.chatim.nonamechatim.service.UserService;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import static com.chatim.nonamechatim.netty.ServerBoot.CHANNELUSER;
import static com.chatim.nonamechatim.netty.ServerBoot.USERLIST;
import static com.chatim.nonamechatim.netty.handler.ChatHandler.chatHandler;

@Slf4j
@Component
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    private final UserService userService;

    public WebSocketHandler(UserService userService){
        this.userService = userService;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
        // 判断当前是什么操作
        Command command = JSON.parseObject(frame.text(), Command.class);
        switch (CommandType.match(Integer.valueOf(command.getCode()))){
            case CONNECTION -> ConnectionHandler.execute(ctx, command);
            case CHAT -> chatHandler.execute(ctx, frame);
            case HEARTBEAT -> log.info("心跳检测：{}",ctx);
            default -> ctx.channel().writeAndFlush(WSRes.fail("不支持的操作"));
        }
    }

    /**
     * 心跳检测
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent idleStateEvent) {
            // 读空闲
            if (idleStateEvent.state() == IdleState.READER_IDLE) {
                // 断开用户的连接
                Long id = CHANNELUSER.get(ctx.channel().id());
                userService.update(new LambdaUpdateWrapper<User>().eq(User::getId, id).set(User::getActiveStatus, 2));
                USERLIST.remove(id);
                CHANNELUSER.remove(ctx.channel().id());
                ctx.channel().close();
            }
        }
        super.userEventTriggered(ctx, evt);
    }

    /**
     * 断开连接
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        // 用户离线
        log.info("断开连接：{}",ctx);
        Long id = CHANNELUSER.get(ctx.channel().id());
        userService.update(new LambdaUpdateWrapper<User>().eq(User::getId, id).set(User::getActiveStatus, 2));
        USERLIST.remove(id);
        CHANNELUSER.remove(ctx.channel().id());
        super.handlerRemoved(ctx);
    }
}
